/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.community.controller.manage;

import cn.ac.nercis.pes.common.constant.manage.EvaluationEntryMode;
import cn.ac.nercis.pes.common.constant.manage.EvaluationPasteMethod;
import cn.ac.nercis.pes.community.component.dialog.MessageType;
import cn.ac.nercis.pes.community.controller.base.GlobalEventHandle;
import cn.ac.nercis.pes.community.controller.base.InitDataLoad;
import cn.ac.nercis.pes.community.service.SysConfigService;
import cn.ac.nercis.pes.community.support.FXMLController;
import cn.ac.nercis.pes.community.utils.*;
import cn.ac.nercis.pes.community.views.project.TaskManageView;
import cn.ac.nercis.pes.model.dto.manage.AppConfigDTO;
import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.layout.StackPane;
import javafx.stage.DirectoryChooser;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.File;
import java.net.URL;
import java.util.Objects;
import java.util.Optional;
import java.util.ResourceBundle;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * 存储路径管理控制器
 * @author zpy
 * @version 1.0.0
 */
@FXMLController
public class PathManageController implements Initializable, GlobalEventHandle, InitDataLoad {
    @FXML
    private StackPane page;
    @FXML
    private Label titleLabel;
    @FXML
    private Button saveButton;

    @FXML
    private Button backButton;
    @FXML
    private TextField txtDoc;

    @FXML
    private ToggleGroup inputGroup;
    @FXML
    private ToggleGroup pasteGroup;
    @FXML
    private RadioButton unifiedMode;
    @FXML
    private RadioButton dakMode;
    @FXML
    private RadioButton addMode;
    @FXML
    private RadioButton clearMode;

    private final SysConfigService configService;
    private final ExecutorService executor;

    @Autowired
    public PathManageController(SysConfigService configService,
                                ExecutorService executor) {
        this.configService = configService;
        this.executor = executor;
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        titleLabel.setGraphic(IconUtils.getGlyph("config-icon", "title-icon"));
        saveButton.setGraphic(IconUtils.getGlyph("save-button-icon", "btn-icon"));
        backButton.setGraphic(IconUtils.getGlyph("back-button-icon", "btn-icon"));
        GuiStore.applyQuickSave(this.page, this::onGlobalSave);
    }

    @Override
    public void initializeData() {
        this.loadData();
    }

    @Override
    public void onGlobalSave() {
        this.onSave();
    }

    @FXML
    public void onBack() {
        var taskManageView = SpringUtils.getBean(TaskManageView.class).getView();
        GuiStore.setMainBodyContent(taskManageView);
    }

    @FXML
    public void onSave() {
        if (StringUtils.isBlank(txtDoc.getText())) {
            AppUtils.showMessageDialog("默认存储路径不能为空",MessageType.WARN,this.page);
            return;
        }
        var config = collectAppConfigData();
        CompletableFuture.supplyAsync(() -> this.configService.saveConfiguration(config))
                .thenAccept(res -> Platform.runLater(() -> {
                    if (res.isSuccess()) {
                        AppUtils.showMessageDialog("保存成功", MessageType.SUCCESS,this.page);
                    } else {
                        AppUtils.showMessageDialog(res.getMsg(),MessageType.FAIL,this.page);
                    }
                }))
                .exceptionally((ex) -> {
                    AppUtils.showMessageDialog("保存配置信息失败",MessageType.FAIL,this.page);
                    return null;
                });;

    }

    public AppConfigDTO collectAppConfigData() {
        return AppConfigDTO.builder()
                .rootPath(this.txtDoc.getText())
                .entryMode(EvaluationEntryMode.DAK_MODE)
                .pasteMethod(EvaluationPasteMethod.getPasteMethodByName(getSelectedRadioText(pasteGroup)))
                .build();
    }

    private String getSelectedRadioText(ToggleGroup toggleGroup) {
        return Optional.ofNullable((RadioButton) toggleGroup.getSelectedToggle())
                .map(RadioButton::getText)
                .orElse("");
    }

    @FXML
    public void onDoc() {
        this.selectPath(txtDoc);
    }

    private void loadData() {
        CompletableFuture.supplyAsync(this.configService::getConfiguration,executor)
                .thenAccept(res->Platform.runLater(()-> initConfigData(res)))
                .exceptionally((ex) -> {
                    AppUtils.showMessageDialog("加载配置信息失败",MessageType.WARN,this.page);
                    return null;
                });
    }

    private void initConfigData(AppConfigDTO config){
        this.txtDoc.setText(config.getRootPath());
        selectRadioButton(this.unifiedMode,config.getEntryMode().getName());
        selectRadioButton(this.dakMode,config.getEntryMode().getName());

        selectRadioButton(this.addMode,config.getPasteMethod().getName());
        selectRadioButton(this.clearMode,config.getPasteMethod().getName());

    }

    private void selectRadioButton(RadioButton rbx,String text){
        rbx.setSelected(StringUtils.equals(rbx.getText(),text));
    }

    private void selectPath(TextField textField){
        DirectoryChooser fileChooser = new DirectoryChooser();
        fileChooser.setTitle("选择存储路径");
        if(StringUtils.isNotBlank(textField.getText()) && FileUtils.getFile(textField.getText()).exists()){
            fileChooser.setInitialDirectory(FileUtils.getFile(textField.getText()));
        }else{
            fileChooser.setInitialDirectory(FileUtils.getFile(SystemUtils.getHomeDirectory()));
        }
        File filePath = fileChooser.showDialog(GuiStore.getStage());
        if (Objects.isNull(filePath)) {
            return;
        }
        textField.setText(filePath.getPath());
    }
}